#!/bin/bash

# SSL证书自动续期脚本
# 用于定时任务，自动续期Let's Encrypt证书

set -e

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"
}

# 项目目录
PROJECT_DIR="/path/to/pecco-pet-shop"  # 请修改为实际项目路径
DOMAIN="pecco.pet"  # 请修改为实际域名

# 切换到项目目录
cd "$PROJECT_DIR" || {
    log_error "无法切换到项目目录: $PROJECT_DIR"
    exit 1
}

# 检查证书是否需要续期
check_certificate_expiry() {
    log_info "检查证书过期时间..."
    
    if [ ! -f "/etc/letsencrypt/live/$DOMAIN/fullchain.pem" ]; then
        log_error "证书文件不存在: /etc/letsencrypt/live/$DOMAIN/fullchain.pem"
        return 1
    fi
    
    # 获取证书过期时间
    expiry_date=$(openssl x509 -enddate -noout -in "/etc/letsencrypt/live/$DOMAIN/fullchain.pem" | cut -d= -f2)
    expiry_timestamp=$(date -d "$expiry_date" +%s)
    current_timestamp=$(date +%s)
    
    # 计算剩余天数
    days_left=$(( (expiry_timestamp - current_timestamp) / 86400 ))
    
    log_info "证书剩余有效期: $days_left 天"
    
    # 如果剩余天数少于30天，则需要续期
    if [ $days_left -lt 30 ]; then
        log_info "证书即将过期，需要续期"
        return 0
    else
        log_info "证书仍然有效，无需续期"
        return 1
    fi
}

# 续期证书
renew_certificate() {
    log_info "开始续期SSL证书..."
    
    # 停止nginx容器以释放80端口
    log_info "临时停止nginx容器..."
    docker-compose -f docker-compose.prod.yml stop nginx
    
    # 续期证书
    log_info "执行证书续期..."
    if certbot renew --standalone --non-interactive; then
        log_info "证书续期成功"
    else
        log_error "证书续期失败"
        # 重启nginx容器
        docker-compose -f docker-compose.prod.yml start nginx
        exit 1
    fi
    
    # 复制新证书到项目目录
    log_info "复制新证书到项目目录..."
    cp /etc/letsencrypt/live/$DOMAIN/fullchain.pem ./ssl-certs/
    cp /etc/letsencrypt/live/$DOMAIN/privkey.pem ./ssl-certs/
    
    # 设置权限
    chmod 644 ./ssl-certs/fullchain.pem
    chmod 600 ./ssl-certs/privkey.pem
    
    # 重启nginx容器
    log_info "重启nginx容器..."
    docker-compose -f docker-compose.prod.yml start nginx
    
    # 等待nginx启动
    sleep 10
    
    # 验证新证书
    log_info "验证新证书..."
    if curl -s -I "https://$DOMAIN" | grep -q "200"; then
        log_info "新证书验证成功"
    else
        log_warn "新证书验证可能有问题"
    fi
}

# 发送通知（可选）
send_notification() {
    local message="$1"
    local status="$2"
    
    # 这里可以添加邮件通知、钉钉通知等
    # 例如发送邮件：
    # echo "$message" | mail -s "SSL证书续期通知 - $status" admin@pecco.pet
    
    log_info "通知: $message"
}

# 主函数
main() {
    log_info "开始SSL证书续期检查..."
    
    # 检查是否为root用户
    if [ "$EUID" -ne 0 ]; then
        log_error "请使用root权限运行此脚本"
        exit 1
    fi
    
    # 检查证书是否需要续期
    if check_certificate_expiry; then
        # 需要续期
        if renew_certificate; then
            send_notification "SSL证书续期成功" "SUCCESS"
            log_info "SSL证书续期完成"
        else
            send_notification "SSL证书续期失败" "FAILED"
            log_error "SSL证书续期失败"
            exit 1
        fi
    else
        # 不需要续期
        log_info "证书仍然有效，无需续期"
    fi
    
    log_info "SSL证书续期检查完成"
}

# 运行主函数
main "$@"
